# @Time    : 2025/7/26 10:29
# @Author: Fioman
# @Phone  : 13149920693
# @Tips      : Talk is cheap,show me the code ^_^
import os

import cv2 as cv
import numpy as np


def safe_imread(image_path):
    """
    安全读取图片，支持中文路径
    :param image_path: 图片路径
    :return: 图片数组，如果读取失败返回None
    """
    try:
        # 使用np.fromfile读取文件，然后使用cv.imdecode解码
        # 这样可以避免OpenCV imread对中文路径的编码问题
        image_array = np.fromfile(image_path, dtype=np.uint8)
        image = cv.imdecode(image_array, cv.IMREAD_COLOR)
        return image
    except Exception as e:
        print(f"读取图片失败: {image_path}, 错误: {e}")
        return None


def get_total_images(image_root):
    """
    获取所有的图像,有四个
    :param image_root:
    :return:
    """
    # 1.遍历目录下的图片,获取所有的文件名
    image_dict = {}
    for file in os.listdir(image_root):
        if file.endswith('.jpg') or file.endswith('.png'):
            image_path = os.path.join(image_root, file)
            image = safe_imread(image_path)

            if image is None:
                print(f"跳过无法读取的图片: {image_path}")
                continue

            if "3DMark" in file:
                image_dict["3DMark"] = image
            elif "furmark" in file:
                image_dict["furmark"] = image
            elif "GPU-Z" in file:
                image_dict["GPU-Z"] = image
            elif "ComputerZ_CN":
                image_dict["ludashi"] = image

    # 检查是否成功读取了所有需要的图片
    required_images = ["3DMark", "furmark", "GPU-Z", "ludashi"]
    missing_images = [img for img in required_images if img not in image_dict]

    if missing_images:
        print(f"警告: 缺少以下图片: {missing_images}")

    return image_dict


def resize_image_to_width(image, target_width):
    """
    将图像按宽度等比例缩放
    :param image: 输入图像
    :param target_width: 目标宽度
    :return: 缩放后的图像
    """
    height, width = image.shape[:2]
    ratio = target_width / width
    new_height = int(height * ratio)
    return cv.resize(image, (target_width, new_height))


def resize_image_to_height(image, target_height):
    """
    将图像按高度等比例缩放
    :param image: 输入图像
    :param target_height: 目标高度
    :return: 缩放后的图像
    """
    height, width = image.shape[:2]
    ratio = target_height / height
    new_width = int(width * ratio)
    return cv.resize(image, (new_width, target_height))


def crop_bottom_quarter(image, extra_crop_pixels=0):
    """
    截掉图片下面1/4的部分，并可选择额外减少指定像素数
    :param image: 输入图像
    :param extra_crop_pixels: 额外减少的像素数
    :return: 裁剪后的图像
    """
    height, width = image.shape[:2]
    # 保留上面3/4的部分，截掉下面1/4
    new_height = int(height * 0.9)
    # 额外减少指定像素数
    new_height = max(1, new_height - extra_crop_pixels)  # 确保至少保留1个像素
    return image[:new_height, :]


def joint_image(image_dict):
    """
    拼接图像
    :param image_dict:
    :return: 拼接后的图像
    """
    image_3d = image_dict["3DMark"]
    image_furmark = image_dict["furmark"]
    image_gpu_z = image_dict["GPU-Z"]
    image_ludashi = image_dict["ludashi"]

    # 打印这些图片的size
    print(f"3d.size:{image_3d.shape[:2]},furmark.size:{image_furmark.shape[:2]},gpu_z.size:{image_gpu_z.shape[:2]},ludashi.size:{image_ludashi.shape[:2]}")

    # 1. 先裁剪3DMark和FurMark，截掉下面1/4
    # 3DMark额外减少100像素
    image_3d_cropped = crop_bottom_quarter(image_3d, extra_crop_pixels=80)
    image_furmark_cropped = crop_bottom_quarter(image_furmark)

    print(f"裁剪后 - 3d.size:{image_3d_cropped.shape[:2]}, furmark.size:{image_furmark_cropped.shape[:2]}")

    # 2. 3DMark和FurMark垂直拼接
    # 统一宽度为3DMark的宽度
    target_width = image_3d_cropped.shape[1]
    furmark_resized = resize_image_to_width(image_furmark_cropped, target_width)

    # 垂直拼接3DMark和FurMark
    top_section = np.vstack([image_3d_cropped, furmark_resized])
    print(f"顶部拼接区域尺寸: {top_section.shape[:2]}")

    # 3. 鲁大师和GPU-Z水平拼接
    # 统一高度为鲁大师的高度
    target_height = image_ludashi.shape[0]
    gpu_z_resized = resize_image_to_height(image_gpu_z, target_height)

    # 水平拼接鲁大师和GPU-Z
    bottom_section = np.hstack([image_ludashi, gpu_z_resized])
    print(f"底部拼接区域尺寸: {bottom_section.shape[:2]}")

    # 4. 将两个拼接结果垂直拼接
    # 统一宽度为顶部区域的宽度
    bottom_width = top_section.shape[1]
    bottom_resized = resize_image_to_width(bottom_section, bottom_width)

    # 最终垂直拼接
    final_image = np.vstack([top_section, bottom_resized])
    print(f"最终拼接图像尺寸: {final_image.shape[:2]}")

    # 5. 整体缩放到原来的0.8倍
    height, width = final_image.shape[:2]
    new_width = int(width * 0.75)
    new_height = int(height * 0.75)
    final_image_resized = cv.resize(final_image, (new_width, new_height))
    print(f"缩放后最终图像尺寸: {final_image_resized.shape[:2]}")

    return final_image_resized


def save_jointed_image(image, output_path):
    """
    保存拼接后的图像，支持中文路径
    :param image: 拼接后的图像
    :param output_path: 输出路径
    """
    try:
        # 使用cv.imencode编码图片，然后写入文件
        # 这样可以避免OpenCV imwrite对中文路径的编码问题
        success, encoded_image = cv.imencode('.jpg', image)
        if success:
            encoded_image.tofile(output_path)
            print(f"拼接图像已保存到: {output_path}")
        else:
            print(f"保存图片失败: {output_path}")
    except Exception as e:
        print(f"保存图片时发生错误: {output_path}, 错误: {e}")


